<style type="text/css"> 
#tooltip {
  position:absolute ;
  top:0 ;
  left:0 ;
  border:1 solid black ;
  background:#FFFFCC ;
  color:black ;
  font-size:9pt ;
  padding:4 ;
  z-index:10 ;
  display:none ;
}

#edit_form {
  position:absolute ;
  border:1 solid black ;
  background:#FFFFCC ;
  padding:4 ;
  z-index:11 ;
  display:none ;
}
</style>
<script type="text/javascript">

var storageId = 'extension_storage_id' ;
var toolTip ;
var editForm ;
var maxId ;

function showTip( id, text ) {

  toolTip.name = id ;

  toolTip.style.pixelTop  = event.y + document.body.scrollTop ; 
  toolTip.style.pixelLeft = event.x + document.body.scrollLeft + 10 ; 

  toolTip.innerText = text ;
  toolTip.style.display = "inline" ;

}

function hideTip( ) {
  toolTip.style.display = "none" ;
  toolTip.name = 0 ;
}

function showEditForm( tr ) {
  editForm.style.pixelTop  = event.y + document.body.scrollTop ; 
  editForm.style.pixelLeft = event.x + document.body.scrollLeft + 10 ; 

  writeEditForm( readTr( tr ) ) ;

  editForm.style.display = "inline" ;
  editForm.name = tr.id ;
}

function hideEditForm( ) {
  editForm.style.display = "none" ;
  editForm.name = 0 ;
}

function soundWaveData( uri ) {
  var audio = new Audio( uri ) ;
  audio.play( ) ;
  removeLoading( ) ;
}

function displayWaveData( uri ) {
  removeLoading( ) ;

  var resultArea = getResultArea( ) ;
  var a = document.createElement( 'a' ) ;
  a.href = uri ;
  var text = document.createTextNode( 'download' ) ;
  a.appendChild( text ) ;
  resultArea.appendChild( a ) ;

}

function getResultArea( ) {
  return document.getElementById( 'extension_result_id' ) ;
}

function displayLoading( str ) {
  removeLoading( ) ;

  var resultArea = getResultArea( ) ;
  var loading = document.createTextNode( str ) ;
  resultArea.appendChild( loading ) ;
}

function removeLoading( ) {
  var resultArea = getResultArea( ) ;
  var child = resultArea.firstChild ;

  if( child )
    resultArea.removeChild( child ) ;
}

function accessMS( callback ) {
  displayLoading( 'loading...' ) ;
  var words = document.getElementsByName( 'words' ) ;
  text = '' ;
  for( var i = 0; i < words.length; i++ ) {
    if( words[ i ].checked )
      text += encodeURIComponent( readTr( words[ i ].parentElement.parentElement ).word + ".\n" ) ;
  }
  if( text )
    accessServer( text, callback ) ;
  else
    removeLoading( ) ;
}

function speak( ) {
  accessMS( soundWaveData ) ;
}

function download( ) {
  accessMS( displayWaveData ) ;
}

function saveData( ) {
  displayLoading( 'saving...' ) ;
  var words = document.getElementsByName( 'element' ) ;
  var values = new Array( ) ;
  for( var i = 0; i < words.length; i++ ) {
    values.push( readTr( words[ i ] ) ) ;
  }
  chrome.extension.getBackgroundPage( ).localStorage.setItem( storageId, JSON.stringify( values ) ) ;
  displayLoading( 'saved.' ) ;
}

function loadData( ) {

  if( chrome.extension.getBackgroundPage( ).localStorage.getItem( storageId ) ) {
    hideTip( ) ;
    hideEditForm( ) ;
    closeExportArea( ) ;
    closeImportArea( ) ;
    displayLoading( 'loading...' ) ;
    var table = getTable( ) ;
    var child = table.getElementsByTagName( 'tr' )[ 1 ] ;
    while( child ) {
      var tmp_child = child.nextSibling ;
      table.firstChild.removeChild( child ) ;
      child = tmp_child ;
    }
    var values = JSON.parse( chrome.extension.getBackgroundPage( ).localStorage.getItem( storageId ) ) ;
    maxId = 0 ;
    for( var i = 0; i < values.length; i++ ) {
      addWord( values[ i ].flag, values[ i ].word, values[ i ].note, values[ i ].uri ) ;
    }
    displayLoading( 'loaded.' ) ;
  } else {
    displayLoading( 'doesn\'t have save data.' ) ;
  }

}

function clearData( ) {

  if( ! confirm( 'are you sure to clear all data?' ) )
    return ;

  chrome.extension.getBackgroundPage( ).localStorage.setItem( storageId, JSON.stringify( new Array( ) ) ) ;
  loadData( ) ;
  displayLoading( 'cleared.' ) ;
}

function closeExportArea( ) {
  var span = document.getElementById( 'export_span' ) ;
  span.style.display = "none" ;
}

function closeImportArea( ) {
  var span = document.getElementById( 'import_span' ) ;
  span.style.display = "none" ;
}

function exportData( ) {
  closeImportArea( ) ;
  var span = document.getElementById( 'export_span' ) ;
  if( span.style.display == "none" ) {
    span.style.display = "" ;
    var text = '' ;
    var words = document.getElementsByName( 'element' ) ;
    for( var i = 0; i < words.length; i++ ) {
      var values = readTr( words[ i ] ) ;
      values.flag = String( values.flag ).replace( /,/g, '%2C' ) ;
      values.word = values.word.replace( /,/g, '%2C' ) ;
      values.note = values.note.replace( /,/g, '%2C' ) ;
      values.uri  = values.uri.replace( /,/g, '%2C' ) ;
      text += values.flag + ',' + values.word + ',' + values.note + ',' + values.uri + "\n" ;
    }
    var area = document.getElementById( 'export_textarea' ) ;
    area.value = text ;
    displayLoading( 'exported as csv.' ) ;
  } else {
    closeExportArea( ) ;
    removeLoading( ) ;
  }
}

function readTr( tr ) {
  tds = tr.getElementsByTagName( 'td' ) ;
  var flag = tds[ 0 ].firstChild.checked ;
  var word = tds[ 1 ].firstChild.text ;
  var note = tds[ 2 ].firstChild.nodeValue ;
  var uri  = tds[ 3 ].firstChild.href ;
  return { 'flag' : flag, 'word' : word, 'note' : note, 'uri' : uri } ;
}

function writeTr( tr, values ) {
  tds = tr.getElementsByTagName( 'td' ) ;
//  tds[ 0 ].firstChild.checked   = values.flag ;
  tds[ 1 ].firstChild.innerHTML = values.word ;
  tds[ 2 ].firstChild.nodeValue = values.note ;
  tds[ 3 ].firstChild.href      = values.uri ;
  tds[ 3 ].firstChild.innerHTML = extractURI( values.uri ) ;
}

function readEditForm( ) {
  var inputs = editForm.getElementsByTagName( 'input' ) ;
  var word = inputs[ 0 ].value ;
  var note = inputs[ 1 ].value ;
  var uri  = inputs[ 2 ].value ;
  return { 'word' : word, 'note' : note, 'uri' : uri } ;
}

function writeEditForm( values ) {
  var inputs = editForm.getElementsByTagName( 'input' ) ;
  inputs[ 0 ].value = values.word ;
  inputs[ 1 ].value = values.note ;
  inputs[ 2 ].value = values.uri ;
}

function openImportArea( ) {
  closeExportArea( ) ;
  var span = document.getElementById( 'import_span' ) ;
  if( span.style.display == "none" ) {
    span.style.display = "" ;
    displayLoading( 'enter the data as csv.' ) ;
  } else {
    span.style.display = "none" ;
    removeLoading( ) ;
  }
}

function importData( ) {
  closeExportArea( ) ;
  var area = document.getElementById( 'import_textarea' ) ;
  var text = area.value ;
  var array = text.split( "\n" ) ;
  for( var i = 0; i < array.length; i++ ) {
    var values = array[ i ].split( ',' ) ;
    if( values[ 1 ] ) {
      addWord( values[ 0 ].replace( /%2C/g, ',' ) == 'true' ? true : false,
               values[ 1 ].replace( /%2C/g, ',' ),
               values[ 2 ].replace( /%2C/g, ',' ),
               values[ 3 ].replace( /%2C/g, ',' ) ) ;
    }
  }
  area.value = '' ;
  displayLoading( 'imported. but not saved yet.' ) ;
  closeImportArea( ) ;
}

function accessServer( text, callback ) {

  var xhr = new XMLHttpRequest( ) ;
  xhr.onreadystatechange = function( ) {
    if( xhr.readyState == 4 && xhr.status == 200 ) {
      callback( eval( xhr.responseText ) ) ;
    }
  }

  var complete = function( result ) {
    speakMS( text, result, callback ) ;
  } ;

  var uri = 'http://wl-translate.appspot.com/?action=speak&text=' + text ;
  xhr.open( 'GET', uri, true ) ;
  xhr.send( ) ;

}

function extractURI( uri ) {
  if( uri.length > 30 ) {
    uri.match( /^(.{30})/ ) ;
    return RegExp.$1 + '...' ;
  }
  return uri ;
}

function edit( tr ) {

  if( editForm.name == tr.id ) {
    hideEditForm( ) ;
    return ;
  }

  showEditForm( tr ) ;

}

function update( ) {

  var tr = document.getElementById( editForm.name ) ;
  if( ! tr )
    return ;

  writeTr( tr, readEditForm( ) ) ;

  hideEditForm( ) ;

}

function remove( tr ) {
  var table = tr.parentElement ;
  if( toolTip.name == tr.id ) {
    hideTip( ) ;
  }
  if( editForm.name == tr.id ) {
    hideEditForm( ) ;
  }
  if( tr.nextSibling && tr.nextSibling.name == 'edit_form' ) {
    table.removeChild( tr.nextSibling ) ;
  }
  table.removeChild( tr ) ;
}

function displayDescription( id, word ) {

  if( toolTip.name == id ) {
    hideTip( ) ;
    return ;
  }

  hideTip( ) ;
  showTip( 0, 'loading...' ) ;

  var xhr = new XMLHttpRequest( ) ;
  xhr.onreadystatechange = function( ) {
    if( xhr.readyState == 4 && xhr.status == 200 ) {
      var doc = xhr.responseXML ;
      var result ;
      if( doc.getElementsByTagName( 'WordDefinition' )[ 1 ] ) {
        result = doc.getElementsByTagName( 'WordDefinition' )[ 1 ].firstChild.nodeValue ;
        var values = result.split( "\n" ) ;
        result = '' ;
        for( var i = 0; i < values.length; i++ ) {
          if( values[ i ].match( /^\s*[nv] [0-9]+:/ ) ) {
            result += values[ i ].replace( /^  /, '' ) + "\n" ;
          } else if( values[ i ].match( /^\s*adj [0-9]+:/ ) ) {
            result += values[ i ].replace( /^    /, '' ) + "\n" ;
          } else {
            result += values[ i ] + "\n" ;
          }
        }
      } else {
        result = 'sorry, not found.' ;
      }
      showTip( id, result ) ;
    }
  }

  uri = 'http://services.aonaware.com/DictService/DictService.asmx/DefineInDict?'
      + 'dictId=wn&'
      + 'word=' + encodeURIComponent( word ) ;

  xhr.open( 'GET', uri, true ) ;
  xhr.send( ) ;

}

function addWord( flag, word, note, uri ) {
  var table = getTable( ) ;

  var tr = document.createElement( 'tr' ) ;
  tr.setAttribute( 'name', 'element' ) ;
  tr.id = ++maxId ;

  var td1 = document.createElement( 'td' ) ;
  var checkbox = document.createElement( 'input' ) ;
  checkbox.type = 'checkbox' ;
  checkbox.name = 'words' ;
  checkbox.checked = flag ;
  td1.appendChild( checkbox ) ;

  var td2 = document.createElement( 'td' ) ;
  var wordA = document.createElement( 'a' ) ;
  wordA.href = 'javascript:void( 0 )' ;
  wordA.setAttribute( 'onclick', 'displayDescription( this.parentElement.parentElement.id, this.text )' ) ;
  wordA.appendChild( document.createTextNode( word ) ) ;
  td2.appendChild( wordA ) ;

  var td3 = document.createElement( 'td' ) ;
  td3.appendChild( document.createTextNode( note ) ) ;

  var td4 = document.createElement( 'td' ) ;
  var uriA = document.createElement( 'a' ) ;
  uriA.href = uri ;
  uriA.target = '_blank' ;
  uriA.appendChild( document.createTextNode( extractURI( uri ) ) ) ;
  td4.appendChild( uriA ) ;

  var td5 = document.createElement( 'td' ) ;
  var edit = document.createElement( 'input' ) ;
  edit.type = 'button' ;
  edit.value = 'edit' ;
  edit.setAttribute( 'onclick', 'edit( this.parentElement.parentElement )' ) ;
  td5.appendChild( edit ) ;

  var td6 = document.createElement( 'td' ) ;
  var remove = document.createElement( 'input' ) ;
  remove.type = 'button' ;
  remove.value = 'remove' ;
  remove.setAttribute( 'onclick', 'remove( this.parentElement.parentElement )' ) ;
  td6.appendChild( remove ) ;

  tr.appendChild( td1 ) ;
  tr.appendChild( td2 ) ;
  tr.appendChild( td3 ) ;
  tr.appendChild( td4 ) ;
  tr.appendChild( td5 ) ;
  tr.appendChild( td6 ) ;
  table.firstChild.appendChild( tr ) ;

}

function getTable( ) {
  return document.getElementById( 'extension_table_id' ) ;
}

function onRequest( request, sender, callback ) {

  if( request.action == 'addWord' ) {
    addWord( true, request.word, request.note, request.uri ) ;
    callback( ) ;
  }

}

function allCheck( ) {
  allFlagSet( true ) ;
}

function allClear( ) {
  allFlagSet( false ) ;
}

function allFlagSet( flag ) {
  var boxes = document.getElementsByName( 'words' ) ;
  for( var i = 0; i < boxes.length; i++ ) {
    boxes[ i ].checked = flag ;
  }
}

function init( ) {
  toolTip = document.getElementById( 'tooltip' ) ;
  tipValue = '' ;
  maxId = 0 ;

  editForm = document.getElementById( 'edit_form' ) ;

  var exportSpan = document.getElementById( 'export_span' ) ;
  exportSpan.style.display = "none" ;

  var importSpan = document.getElementById( 'import_span' ) ;
  importSpan.style.display = "none" ;

  var div = document.getElementById( 'extension_div_id' ) ;
  var table = document.createElement( 'table' ) ;
  table.setAttribute( 'id', 'extension_table_id' ) ;
  var tbody = document.createElement( 'tbody' ) ;
  var tr = document.createElement( 'tr' ) ;

  var th1 = document.createElement( 'th' ) ;
  th1.appendChild( document.createTextNode( 'check' ) ) ;

  var th2 = document.createElement( 'th' ) ;
  th2.appendChild( document.createTextNode( 'word' ) ) ;

  var th3 = document.createElement( 'th' ) ;
  th3.appendChild( document.createTextNode( 'note' ) ) ;

  var th4 = document.createElement( 'th' ) ;
  th4.appendChild( document.createTextNode( 'URL' ) ) ;

  var th5 = document.createElement( 'th' ) ;
  th5.appendChild( document.createTextNode( 'edit' ) ) ;

  var th6 = document.createElement( 'th' ) ;
  th6.appendChild( document.createTextNode( 'remove' ) ) ;

  tr.appendChild( th1 ) ;
  tr.appendChild( th2 ) ;
  tr.appendChild( th3 ) ;
  tr.appendChild( th4 ) ;
  tr.appendChild( th5 ) ;
  tr.appendChild( th6 ) ;
  tbody.appendChild( tr ) ;
  table.appendChild( tbody ) ;
  div.insertBefore( table, div.firstChild ) ;
  loadData( ) ;
}

chrome.extension.onRequest.addListener( onRequest ) ;
window.onload = init ;

</script>
<pre><span id="tooltip"></span></pre>
<span id="edit_form">
word<input type="text"><br />
note<input type="text"><br />
URL <input type="text"><br />
<input type="button" value="ok" onclick="update( )"><br />
</span>
<div align="center" id="extension_div_id">
<input type="button" value="all check" id="all_check_button" onclick="allCheck( )" />
<input type="button" value="all clear" id="all_clear_button" onclick="allClear( )" />
<br />
<input type="button" value="speak" id="speak_button" onclick="speak( )" />
<input type="button" value="download" id="download_button" onclick="download( )" />
<input type="button" value="export" id="export_button" onclick="exportData( )" />
<input type="button" value="import" id="import_button" onclick="openImportArea( )" />
<input type="button" value="save" id="save_button" onclick="saveData( )" />
<input type="button" value="load" id="load_button" onclick="loadData( )" />
<input type="button" value="clear" id="clear_button" onclick="clearData( )" />
<div id="extension_result_id"></div>
<span id="export_span">
<textarea cols=50 rows=5 id="export_textarea"></textarea>
</span>
<span id="import_span">
<textarea cols=50 rows=5 id="import_textarea"></textarea><br />
<input type="button" value="ok" onclick="importData( )">
</span>
</div>
